#Requires AutoHotkey v2.0

; GUI 创建和事件绑定
g1 := Gui("+AlwaysOnTop", "IP信息查看器 - 多种方法比较")
txt1 := g1.Add("Text", "w600 h300 VScroll", "")

; 添加多个按钮来测试不同方法
bt1 := g1.Add("Button", "x10 y320 w120 h30", "原始方法")
bt2 := g1.Add("Button", "x140 y320 w120 h30", "文件方式")
bt3 := g1.Add("Button", "x270 y320 w120 h30", "分块读取")
bt4 := g1.Add("Button", "x400 y320 w120 h30", "逐行读取")
bt5 := g1.Add("Button", "x530 y320 w60 h30", "清空")

bt1.OnEvent("Click", GetIP)
bt2.OnEvent("Click", GetIPWithFile)
bt3.OnEvent("Click", GetIPWithChunks)
bt4.OnEvent("Click", GetIPWithLines)
bt5.OnEvent("Click", ClearText)

g1.Show()
WinActivate(g1)


; 函数定义
GetIP(*) {
    txt1.Value := "正在获取IP信息..."
    res := RunCmd("ipconfig")
    txt1.Value := "原始方法结果：`n" . res
}

GetIPWithFile(*) {
    txt1.Value := "正在获取IP信息（文件方式）..."
    res := RunCmdWithFile("ipconfig")
    txt1.Value := "文件方式结果：`n" . res
}

GetIPWithChunks(*) {
    txt1.Value := "正在获取IP信息（分块读取）..."
    res := RunCmdWithChunks("ipconfig")
    txt1.Value := "分块读取结果：`n" . res
}

GetIPWithLines(*) {
    txt1.Value := "正在获取IP信息（逐行读取）..."
    res := RunCmdWithLines("ipconfig")
    txt1.Value := "逐行读取结果：`n" . res
}

ClearText(*) {
    txt1.Value := "已清空`n`n请点击上方按钮测试不同的命令执行方式：`n"
          . "原始方法 - 使用 exec.StdOut.ReadAll()`n"
          . "文件方式 - 重定向输出到临时文件`n"
          . "分块读取 - 使用 Read()分块读取`n"
          . "逐行读取 - 使用 ReadLine()逐行读取"
}

RunCmd(command) {
    txt1.Value := "运行命令1"
    shell := ComObject("WScript.Shell")
    txt1.Value := "运行命令2"
    exec := shell.Exec(A_ComSpec " /c " command)
    txt1.Value := "运行命令3"
    result := exec.StdOut.ReadAll()
    txt1.Value := "运行命令4"
    return result
}

; ==================== 替代方法 ====================

; 方法1：使用临时文件重定向输出
RunCmdWithFile(command) {
    txt1.Value := "正在执行命令（文件方式）..."
    
    ; 创建临时文件
    tempFile := A_Temp "\\ahk_cmd_" A_TickCount ".txt"
    
    ; 执行命令并重定向输出到文件
    shell := ComObject("WScript.Shell")
    exec := shell.Exec(A_ComSpec " /c " command " > " tempFile " 2>&1")
    
    ; 等待进程完成
    while (exec.Status = 0) {
        Sleep(50)
    }
    
    ; 读取文件内容
    try {
        result := FileRead(tempFile)
        FileDelete(tempFile)
        return result
    } catch Error as e {
        return "读取结果文件时发生错误: " . e.Message
    }
}

; 方法2：使用分块读取方式
RunCmdWithChunks(command) {
    txt1.Value := "正在执行命令（分块读取）..."
    shell := ComObject("WScript.Shell")
    exec := shell.Exec(A_ComSpec " /c " command)
    
    result := ""
    
    ; 循环读取输出流
    while (exec.Status = 0 || !exec.StdOut.AtEndOfStream) {
        ; 检查是否有数据可读
        if (!exec.StdOut.AtEndOfStream) {
            try {
                chunk := exec.StdOut.Read(512)  ; 每次读取512字节
                result .= chunk
            } catch {
                break
            }
        }
        Sleep(10)
    }
    
    return result
}

; 方法3：使用ReadLine逐行读取
RunCmdWithLines(command) {
    txt1.Value := "正在执行命令（逐行读取）..."
    shell := ComObject("WScript.Shell")
    exec := shell.Exec(A_ComSpec " /c " command)
    
    result := ""
    
    ; 逐行读取输出
    while (exec.Status = 0 || !exec.StdOut.AtEndOfStream) {
        ; 逐行读取
        if (!exec.StdOut.AtEndOfStream) {
            try {
                line := exec.StdOut.ReadLine()
                result .= line . "`n"
            } catch {
                break
            }
        }
        Sleep(10)
    }
    
    return result
}